from django.contrib.contenttypes.models import ContentType
from rest_framework.permissions import BasePermission, SAFE_METHODS, IsAuthenticated

from permissions.services import PermissionService
from utils.mixins.common_mixins.permissions import OperandHolder, OR

API_ACCESS = 1
API_FORBIDDEN = 0
DOWNLOAD_ACCESS = 1


class IsSuperUserOrReadOnly(BasePermission):
    """
    超级用户权限
    """

    def has_permission(self, request, view):
        return bool(request.method in SAFE_METHODS or request.user and request.user.is_superuser)


class IsSuperUser(IsAuthenticated):
    """
    超级用户权限
    """

    def has_permission(self, request, view):
        return bool(request.user and request.user.is_superuser)


def get_api_permission(user, api_name):
    """
    获取api权限
    :param user:
    :param api_name:
    :return:
    """
    # 获取api名称
    api_name = api_name.lower().replace(' ', '_')
    model_name = 'api'
    content_type = ContentType.objects.get(app_label='permissions', model=model_name)
    permission = PermissionService.get_permission(user, f'{api_name}__api', content_type=content_type)
    return permission.get(api_name, False)


class APIPermission(IsAuthenticated):
    """
    API接口黑名单权限
    """

    def has_permission(self, request, view):
        if not super().has_permission(request, view):
            return False
        user = request.user
        api_name = view.get_view_name()
        permission = get_api_permission(user, api_name)

        return (not permission) or permission.get('status') == API_ACCESS


class DownloadSelfFilePermission(BasePermission):
    """
    下载权限，可以下载自己上传的文件
    """

    def has_object_permission(self, request, view, obj):
        return obj.upload_user == request.user


class DownloadFileTagPermission(BasePermission):
    """
    下载权限，可以下载允许下载的文件（标识为文件标签）
    """

    def has_object_permission(self, request, view, obj):
        file_tag = obj.file_tag
        if file_tag is None:
            return False

        model_name = 'filetag'
        content_type = ContentType.objects.get(app_label='permissions', model=model_name)
        per_names = [f'{tag}__filetag' for tag in file_tag.split(',')]
        permissions = PermissionService.get_permissions(request.user, per_names, content_type=content_type)
        for permission in permissions.values():
            if not permission:
                continue
            for per in permission.values():
                if per.get('status') == DOWNLOAD_ACCESS:
                    return True
        return False


# DefaultPermissionBackend = OperandHolder(OR, IsSuperUser, APIPermission)

class DefaultPermissionBackend(OperandHolder):
    def __init__(self):
        super().__init__(OR, IsSuperUser, APIPermission)
